# plane pro需求的描述：
# 存在四个对象：我方飞机，敌方飞机，我方子弹，敌方子弹
# 功能：我方飞机可以移动(根据按键来控制)，敌方飞机也可以移动(自动随机移动)，双方飞机都可以发射子弹，背景音乐
# 步骤：创建一个窗口，创建一个我方飞机可以根据按键来控制移动，给我方飞机添加发射子弹的功能(按下空格键去发射)，创建一个敌方飞机，敌方飞机可以自由随机移动和发射子弹
# 安装pygame模块的时候如果在pychram中安装失败，可以尝试把在系统层面的python环境中安装的pygame文件夹拷贝到pycharm所创建项目中的venv虚拟环境里面
import pygame
import random#随机产生数据的对象
import time
from pygame.locals import *
# 实现步骤原理和面向过程是一样的，不同的是代码的组织方式不一样：
# 1，创建一个飞机类，实现左移，右移，显示三个功能
# 2，创建一个键盘控制函数，实现键盘的左，右，空格键的功能
# 3，创建主函数，实现创建窗口，背景图片，背景音乐，并实现所有逻辑
class HeroPlane:
    '''1，实现飞机的显示，并且可以控制飞机的移动【面向对象】'''
    def __init__(self,screen):
        '''
        初始化方法
        :param screen: 主窗体对象
        '''
        # 飞机的默认位置
        self.x=150
        self.y=450
        # 接收要显示内容的窗口
        self.screen=screen
        # 生成飞机的图片对象
        self.imageName='./feiji/hero.png'
        self.image=pygame.image.load(self.imageName)
        # 用来存放子弹的列表
        self.bulletList=[]
        pass
    def moveleft(self):
        '''左移动'''
        if self.x>0:
            self.x-=10
        pass
    def moveright(self):
        '''右移动'''
        if self.x<310:
            self.x+=10
        pass
    def display(self):
        '''在主窗口中显示飞机'''
        self.screen.blit(self.image,(self.x,self.y))
        # 完善子弹的展示逻辑
        needDelItemList=[]
        for item in self.bulletList:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        # 重新遍历一下
        for i in needDelItemList:
            self.bulletList.remove(i)
            pass
        for bullet in self.bulletList:
            bullet.display()#显示子弹的位置
            bullet.move()#让这个子弹进行移动，下次再显示的时候就会看到子弹在修改后的位置
        pass
    def biubiubiu(self):
        '''发射子弹'''
        newBullet=Bullet(self.x,self.y,self.screen)
        self.bulletList.append(newBullet)
    pass
class Bullet:
    '''创建子弹类'''
    def __init__(self,x,y,screen):
        '''
        :param x:
        :param y:
        :param screen:
        '''
        self.x=x+13
        self.y=y-20
        self.screen=screen
        self.image=pygame.image.load('./feiji/bullet.png')
        pass
    def display(self):
        self.screen.blit(self.image,(self.x,self.y))
        pass
    def move(self):
        self.y-=3
        pass
    def judge(self):
        '''
        判断子弹是否越界
        :return:
        '''
        if self.y<0:
            return True
        else:
            return False
    pass
class EnemyPlane:
    '''创建敌机类'''
    def __init__(self,screen):
        # 设置默认方向
        self.direction='right'
        # 飞机的默认位置
        self.x = 0
        self.y = 0
        # 接收要显示内容的窗口
        self.screen = screen
        # 生成飞机的图片对象
        self.imageName = './feiji/enemy0.png'
        self.image = pygame.image.load(self.imageName)
        self.bulletList=[]
        pass
    def display(self):
        '''
        显示敌机以及子弹位置信息
        :return:
        '''
        self.screen.blit(self.image,(self.x,self.y))
        pass
        # 完善子弹的展示逻辑
        needDelItemList = []
        for item in self.bulletList:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        # 重新遍历一下
        for i in needDelItemList:
            self.bulletList.remove(i)
            pass
        for bullet in self.bulletList:
            bullet.display()  # 显示子弹的位置
            bullet.move()  # 让这个子弹进行移动，下次再显示的时候就会看到子弹在修改后的位置
        pass
    def biubiu(self):
        '''
        敌机随机发射子弹
        :return:
        '''
        num=random.randint(1,20)
        if num==3:
            newBullet=EnemyBullet(self.x,self.y,self.screen)
            self.bulletList.append(newBullet)
            pass
    def move(self):
        '''
        敌机随机移动
        :return:
        '''
        if self.direction=='right':
            self.x+=2
        elif self.direction=='left':
            self.x-=2
            pass
        if self.x>350-20:
            self.direction='left'
            pass
        elif self.x<0:
            self.direction='right'
            pass
    pass
class EnemyBullet:
    '''创建敌机子弹类'''
    def __init__(self,x,y,screen):
        '''
        :param x:
        :param y:
        :param screen:
        '''
        self.x=x
        self.y=y+10
        self.screen=screen
        self.image=pygame.image.load('./feiji/bullet1.png')
        pass
    def display(self):
        self.screen.blit(self.image,(self.x,self.y))
        pass
    def move(self):
        self.y+=3
        pass
    def judge(self):
        '''
        判断子弹是否越界
        :return:
        '''
        if self.y>500:
            return True
        else:
            return False
    pass
def key_control(HeroObj):
    '''
    定义普通的函数用来实现键盘的检测
    :param HeroObj: 控制检测的对象
    :return:
    '''
    eventlist = pygame.event.get()
    for event in eventlist:
        if event.type == QUIT:
            print('退出')
            exit()
            pass
        elif event.type == KEYDOWN:
            if event.key == K_a or event.key == K_LEFT:
                print('left')
                HeroObj.moveleft()#调用函数实现左移动
                pass
            elif event.key == K_d or event.key == K_RIGHT:
                print('right')
                HeroObj.moveright()#调用函数实现右移动
            elif event.key == K_SPACE:
                print('space')
                HeroObj.biubiubiu()
    pass
def main():
    '''首先创建一个窗口，用来显示内容'''
    screen=pygame.display.set_mode((350,500))
    '''创建一个背景图片'''
    background=pygame.image.load('./feiji/background.png')
    '''设置一个title'''
    pygame.display.set_caption('飞坤大战')
    '''添加背景音乐'''
    pygame.mixer.init()
    pygame.mixer.music.load('./feiji/SWIN-S - 只因你太美.ogg')
    pygame.mixer.music.set_volume(0.2)
    pygame.mixer.music.play(-1)  # 循环次数-1表示无限循环
    '''创建一个飞机对象'''
    hero=HeroPlane(screen)
    '''创建一个敌机对象'''
    enemyplane=EnemyPlane(screen)
    while True:
        '''设定要显示的内容'''
        screen.blit(background, (0, 0))
        '''显示玩家飞机的图片'''
        hero.display()
        '''显示敌机的图片'''
        enemyplane.display()#显示敌机
        enemyplane.move()#敌机运动
        enemyplane.biubiu()#敌机随机发射子弹
        '''获取键盘事件'''
        key_control(hero)
        '''更新显示内容'''
        pygame.display.update()
    pass
if __name__=='__main__':#这允许开发者在模块中编写一些只在模块被直接执行时才运行的代码。
    main()
# 当一个模块被直接执行时，__name__ 的值为 "__main__"。但是，如果一个模块被其他模块导入，那么 __name__ 的值就会被设置为该模块的名字。
